package com.baturu.vin.benz.service.impl;

import com.baturu.carvin.service.impl.AppConfigLoader;
import com.baturu.vin.benz.dto.*;
import com.baturu.vin.dto.EPCAnalyserEnum;
import com.baturu.vin.dto.EPCImagePointDTO;
import com.baturu.vin.dto.EPCPartsImagePositionDTO;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 奔驰vin码和配件编码解析器
 *
 * @author 蒋鑫磊
 * @Time 2016/11/28.
 */
@Service("benzImageService")
public class BenzImageService {

    @Autowired
    private BenzCarTypeInfoService benzCarTypeInfoService;
    @Autowired
    private AppConfigLoader appConfigLoader;


    void fillImageIntoParts(List<BenzEPCPartsInfoDTO> partsInfos) {
        if (CollectionUtils.isEmpty(partsInfos)) {
            return;
        }
        List<BenzImageDTO> imageQueryParam = partsInfos.stream()
                .filter(p -> StringUtils.isNotBlank(p.getCallout()) && !"-----".equals(p.getCallout()))
                .map(p -> BenzImageDTO.builder().catnum(p.getCatNum()).groupnum(p.getGroupNum()).subgrp(p.getSubGroup()).build()
                ).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(imageQueryParam)) {
            return;
        }
        //查询catnum,groupnum,subgrp下所有的图片以及callout
        List<BenzImageDTO> benzImageDTOs = benzCarTypeInfoService.findByPartsCodeByQueryParam(imageQueryParam);

        if (CollectionUtils.isEmpty(benzImageDTOs)) {
            return;
        }
        //将配件中的图片编号以及位置号聚合
        List<BenzImgPositionDTO> imgPositionQueryParam = benzImageDTOs.stream().filter(z -> StringUtils.isNotBlank(z.getCallout())).flatMap(imageDTO ->
                partsInfos.stream().filter(p -> StringUtils.isNotBlank(p.getCallout()) && !"-----".equals(p.getCallout()))
                        .filter(p -> p.getCatNum().equalsIgnoreCase(imageDTO.getCatnum()) && p.getGroupNum().equalsIgnoreCase(imageDTO.getGroupnum())
                                && p.getSubGroup().equalsIgnoreCase(imageDTO.getSubgrp()) && containCallout(p.getCallout(), imageDTO.getCallout()))
                        .map(p -> BenzImgPositionDTO.builder().imgName(imageDTO.getImageCode()).callout(getStandardCallout(p.getCallout())).build())
                        .distinct().collect(Collectors.toList()).stream())
                .distinct().collect(Collectors.toList());

        List<BenzImgPositionDTO> benzImagePositionDTOs = benzCarTypeInfoService.findImgPositionByQueryParam(imgPositionQueryParam);

        partsInfos.forEach(p -> {
            if (StringUtils.isBlank(p.getCallout()) || "-----".equals(p.getCallout())) {
                return;
            }
            List<BenzImageDTO> imageDTOS = benzImageDTOs.stream().filter(z -> p.getCatNum().equalsIgnoreCase(z.getCatnum()) && p.getGroupNum().equalsIgnoreCase(z.getGroupnum())
                    && p.getSubGroup().equalsIgnoreCase(z.getSubgrp()) && containCallout(getStandardCallout(p.getCallout()), z.getCallout())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(imageDTOS)) {
                return;
            }
            BenzImageDTO benzImageDTO = imageDTOS.get(0);
            //图片上可能一个位置对应了两个点
            List<BenzImgPositionDTO> imagePositionDTOs = benzImagePositionDTOs.stream().filter(z -> benzImageDTO.getImageCode().equalsIgnoreCase(z.getImgName()) && getStandardCallout(p.getCallout()).equalsIgnoreCase(z.getCallout())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(imagePositionDTOs)) {
                return;
            }
            p.setImageCallout(Sets.newHashSet(StringUtils.split(benzImageDTO.getCallout(), "  ")));
            p.setImgName(benzImageDTO.getImageCode());
            p.setImageCode(benzImageDTO.getImageCode());
            String catalog = benzImageDTO.getImgtype() + benzImageDTO.getGroupnum() + benzImageDTO.getSubgrp();
            String imageUrl = catalog + "/" + benzImageDTO.getImageCode() + ".png";
            String imgPath = appConfigLoader.getEPCPartsImageFullUrl(EPCAnalyserEnum.BENZ, imageUrl);
            benzImageDTO.setImageUrl(imgPath);
            p.setImgPath(imgPath);
            List<EPCPartsImagePositionDTO> epcPartsImagePositionDTOs = imagePositionDTOs.stream().map(e -> {
                EPCPartsImagePositionDTO epip = new EPCPartsImagePositionDTO();
                EPCImagePointDTO topLeft = new EPCImagePointDTO();
                EPCImagePointDTO bottomRight = new EPCImagePointDTO();
                topLeft.setX(e.getTopLeftX());
                topLeft.setY(e.getTopLeftY());
                bottomRight.setX(e.getBottomRightX());
                bottomRight.setY(e.getBottomRightY());
                epip.setPartsCode(p.getPartsType() + p.getPartNum().trim());
                epip.setPosition(p.getCallout());
                epip.setTopLeft(topLeft);
                epip.setBottomRight(bottomRight);
                return epip;
            }).collect(Collectors.toList());
            p.setPositon(epcPartsImagePositionDTOs);
        });
    }

    String getStandardCallout(String callout) {
        if (callout.length() < 3) {
            return Strings.padStart(callout, 3, '0');
        }
        if (callout.length() == 5) {
            if (callout.startsWith("0")) {
                callout = callout.substring(1, 5);
            }
        }
        if (callout.length() == 4) {
            if (callout.startsWith("0")) {
                callout = callout.substring(1, 4);
            }
        }
        return callout;
    }

    boolean containCallout(String callout, String imageCallout) {
        if (StringUtils.isBlank(callout) || "-----".equals(callout) || StringUtils.isBlank(imageCallout)) {
            return false;
        }
        callout = getStandardCallout(callout);
        return Sets.newHashSet(StringUtils.split(imageCallout, "  ")).contains(callout);
    }


    public List<BenzSuperPartsInfoDTO> setPartsImages(List<BenzSuperPartsInfoDTO> benzSuperPartsInfoDTOS, BenzSuperSubGroupDTO subGroupDTO) {
        if (CollectionUtils.isEmpty(benzSuperPartsInfoDTOS)) {
            return Collections.emptyList();
        }
        List<BenzImageDTO> imageQueryParam = benzSuperPartsInfoDTOS.stream()
                .filter(p -> StringUtils.isNotBlank(p.getCallout()) && !"-----".equals(p.getCallout()))
                .map(p -> BenzImageDTO.builder()
                        .catnum(subGroupDTO.getCatNum())
                        .groupnum(subGroupDTO.getMainGroupNo())
                        .subgrp(subGroupDTO.getSubGroupNo())
                        .build()
                ).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(imageQueryParam)) {
            return benzSuperPartsInfoDTOS;
        }
        //查询catnum,groupnum,subgrp下所有的图片以及callout
        List<BenzImageDTO> benzImageDTOs = benzCarTypeInfoService.findByPartsCodeByQueryParam(imageQueryParam);

        if (CollectionUtils.isEmpty(benzImageDTOs)) {
            return benzSuperPartsInfoDTOS;
        }
        //将配件中的图片编号以及位置号聚合
        List<BenzImgPositionDTO> imgPositionQueryParam = benzImageDTOs.stream().filter(z -> StringUtils.isNotBlank(z.getCallout())).flatMap(imageDTO ->
                benzSuperPartsInfoDTOS.stream().filter(p -> StringUtils.isNotBlank(p.getCallout()) && !"-----".equals(p.getCallout()))
                        .filter(p -> subGroupDTO.getCatNum().equalsIgnoreCase(imageDTO.getCatnum()) && subGroupDTO.getMainGroupNo().equalsIgnoreCase(imageDTO.getGroupnum())
                                && p.getSubGroup().equalsIgnoreCase(imageDTO.getSubgrp()) && containCallout(p.getCallout(), imageDTO.getCallout()))
                        .map(p -> BenzImgPositionDTO.builder().imgName(imageDTO.getImageCode()).callout(getStandardCallout(p.getCallout())).build())
                        .distinct().collect(Collectors.toList()).stream())
                .distinct().collect(Collectors.toList());

        List<BenzImgPositionDTO> benzImagePositionDTOs = benzCarTypeInfoService.findImgPositionByQueryParam(imgPositionQueryParam);

        return benzSuperPartsInfoDTOS.stream().map(p -> {
            if (StringUtils.isBlank(p.getCallout()) || "-----".equals(p.getCallout())) {
                return p;
            }
            List<BenzImageDTO> imageDTOS = benzImageDTOs.stream().filter(z -> subGroupDTO.getCatNum().equalsIgnoreCase(z.getCatnum()) && subGroupDTO.getMainGroupNo().equalsIgnoreCase(z.getGroupnum())
                    && p.getSubGroup().equalsIgnoreCase(z.getSubgrp()) && containCallout(getStandardCallout(p.getCallout()), z.getCallout())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(imageDTOS)) {
                return p;
            }
            BenzImageDTO benzImageDTO = imageDTOS.get(0);
            //图片上可能一个位置对应了两个点
            List<BenzImgPositionDTO> imagePositionDTOs = benzImagePositionDTOs.stream().filter(z -> benzImageDTO.getImageCode().equalsIgnoreCase(z.getImgName()) && getStandardCallout(p.getCallout()).equalsIgnoreCase(z.getCallout())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(imagePositionDTOs)) {
                return p;
            }
            p.setImageCode(benzImageDTO.getImageCode());
            String catalog = benzImageDTO.getImgtype() + benzImageDTO.getGroupnum() + benzImageDTO.getSubgrp();
            String imageUrl = catalog + "/" + benzImageDTO.getImageCode() + ".png";
            String imgPath = appConfigLoader.getEPCPartsImageFullUrl(EPCAnalyserEnum.BENZ, imageUrl);
            benzImageDTO.setImageUrl(imgPath);
            p.setImagePath(imgPath);
            p.setImageCode(benzImageDTO.getImageCode());
            List<EPCPartsImagePositionDTO> epcPartsImagePositionDTOs = imagePositionDTOs.stream().map(e -> {
                EPCPartsImagePositionDTO epip = new EPCPartsImagePositionDTO();
                EPCImagePointDTO topLeft = new EPCImagePointDTO();
                EPCImagePointDTO bottomRight = new EPCImagePointDTO();
                topLeft.setX(e.getTopLeftX());
                topLeft.setY(e.getTopLeftY());
                bottomRight.setX(e.getBottomRightX());
                bottomRight.setY(e.getBottomRightY());
                epip.setPartsCode(p.getBtrPartsCode());
                epip.setPosition(p.getCallout());
                epip.setTopLeft(topLeft);
                epip.setBottomRight(bottomRight);
                return epip;
            }).collect(Collectors.toList());
            p.setEpcPartsImagePositions(epcPartsImagePositionDTOs);
            return p;
        }).collect(Collectors.toList());

    }

}
